/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.generator.entityGenerator.base.dataTypeData.dataTypePropGen.assoUdt;

import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.caf.generator.field.FieldGenerator;
import com.inspur.edp.caf.generator.item.ClassGenerator;
import com.inspur.edp.caf.generator.item.ClassGeneratorContext;
import com.inspur.edp.caf.generator.method.ClassMethodGenerator;
import com.inspur.edp.caf.generator.property.ClassPropertyGenerator;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.collection.GspFieldCollection;
import com.inspur.edp.cef.entity.entity.AssoInfoBase;
import com.inspur.edp.cef.gencommon.MediateType;
import com.inspur.edp.cef.generator.entityGenerator.base.dataTypeData.DataTypeDataGeneratorContext;
import com.inspur.edp.cef.generator.entityGenerator.base.elements.AssoFieldGenerator;
import com.inspur.edp.cef.generator.entityGenerator.base.elements.AssoPropertyGenerator;
import com.inspur.edp.cef.generator.entityGenerator.base.elements.ElementAssoGenerator;
import com.inspur.edp.cef.generator.overall.CefGeneratorContext;
import com.inspur.edp.cef.generator.overall.Utils;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.service.MetadataService;
import com.inspur.edp.udt.designtime.api.entity.SimpleDataTypeDef;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.jdt.core.dom.Modifier;

public class AssoUdtEnrichedInfoGenerator extends ClassGenerator {

  private IGspCommonField field;
  private SimpleDataTypeDef udt;
  private DataTypeDataGeneratorContext dataGenContext;

  public AssoUdtEnrichedInfoGenerator(
      IGspCommonField field, SimpleDataTypeDef udt, DataTypeDataGeneratorContext dataGenContext) {
    super(
        dataGenContext
            .getDataTypeGeneratorContext()
            .getEntityGenContext()
            .getCompilationUnitInfo());
    this.field = field;
    this.udt = udt;
    this.dataGenContext = dataGenContext;
  }

  @Override
  protected void doInitialize() {
    super.doInitialize();
    dataGenContext.getDataTypeGeneratorContext()
        .getEntityGenContext()
        .getElementAssociationTypes()
        .put(field.getID(), new MediateType(dataGenContext.getDataTypeGeneratorContext()
            .getEntityGenContext().getDefaultPackageName(), getName()));
  }

  @Override
  protected ClassGeneratorContext createClassInfoContext() {
    return new ClassGeneratorContext();
  }

  @Override
  protected ArrayList<Modifier.ModifierKeyword> getAccessModifier() {
    return new ArrayList<Modifier.ModifierKeyword>(
        Arrays.asList(new Modifier.ModifierKeyword[]{Modifier.ModifierKeyword.PUBLIC_KEYWORD}));
  }

  @Override
  protected String getName() {
    return getItemName(field);
  }

  public static String getItemName(IGspCommonField field) {
    return Utils.getAssociationTypeName(field);
  }

  public static TypeInfo getItemTypeInfo(IGspCommonField field) {
    return new TypeInfo(Utils.getAssociationTypeName(field)) {{
      setTypePackageName(field.getBelongObject().getGeneratedEntityClassInfo().getClassNamespace());
      setUseFullName(true);
    }};
  }

  //    @Override
  //    protected String getNameSpace() {
  //        return
  // dataGenContext.DataTypeGeneratorContext.DataType.getGeneratedEntityClassInfo().ClassNamespace;
  //    }

  // protected override List<Type>  addParentInterfaces() { return
  //    new List<Type> { typeof(IAuthFieldValue) }; }

  @Override
  protected TypeInfo setParentClass() {
    String packageName = udt.getEntityAssemblyInfo().getAssemblyName();
    String className =
        udt.getContainElements().get(0).getLabelID() + ElementAssoGenerator.nameSuffix;
    CefGeneratorContext cefContext =
        dataGenContext.getDataTypeGeneratorContext().getEntityGenContext().getCefGenContext();
    return Utils.getUdtPropertyTypeList(udt, packageName, className, cefContext).get(0);
  }

//  @Override
//  protected ArrayList<TypeInfo> addParentInterfaces() {
//    String packageName = udt.getEntityAssemblyInfo().getAssemblyName();
//    String className =
//        udt.getContainElements().get(0).getLabelID() + ElementAssoGenerator.nameSuffix;
//    CefGeneratorContext cefContext =
//        dataGenContext.getDataTypeGeneratorContext().getEntityGenContext().getCefGenContext();
//    return Utils.getUdtPropertyTypeList(udt, packageName, className, cefContext);
//  }

  @Override
  protected ArrayList<ClassPropertyGenerator> createPropertyGenerators() {
    GspFieldCollection refEles = field.getChildAssociations().get(0).getRefElementCollection();
    ArrayList<ClassPropertyGenerator> list = new ArrayList<>();
    for (IGspCommonField refEle : refEles) {
      if (refEle.getIsFromAssoUdt()) {
        continue;
      }
      AssoPropertyGenerator gen =
          new AssoPropertyGenerator(
              refEle,
              field.getChildAssociations().get(0),
              dataGenContext.getDataTypeGeneratorContext());
      list.add(gen);
    }
    return list;
  }

  @Override
  protected ArrayList<ClassMethodGenerator> createMethodGenerators() {
    return new ArrayList(Arrays.asList(new AssoUdtEnrichedInfoGetValueGenerator(field),
            new AssoUdtEnrichedInfoSetValueGenerator(dataGenContext, field)));
  }

  @Override
  protected ArrayList<FieldGenerator> createFieldGenerator() {
    ArrayList<FieldGenerator> list = super.createFieldGenerator();
    if (list == null) {
      list = new ArrayList<FieldGenerator>();
    }
    GspFieldCollection refEles = field.getChildAssociations().get(0).getRefElementCollection();
    for (IGspCommonField refEle : refEles) {
      if (refEle.getIsFromAssoUdt()) {
        continue;
      }
      AssoFieldGenerator gen =
          new AssoFieldGenerator(
              refEle,
              field.getChildAssociations().get(0),
              dataGenContext.getDataTypeGeneratorContext());
      list.add(gen);
    }
    return list;
  }

  @Override
  protected ArrayList<ClassMethodGenerator> createConstructorGenerators() {
    return new ArrayList(
        Arrays.asList(
            new ClassMethodGenerator[]{
                new AssoUdtEnrichedInfoDefaultCtorGenerator(udt, getName()),
                new AssoUdtEnrichedInfoCtorGenerator(udt, getName(), dataGenContext)
            }));
  }
}
